package ar.edu.unq.wannaplay.utils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.joda.time.DateTime;
import org.joda.time.Interval;

import ar.edu.unq.wannaplay.calendareable.Licence;
import ar.edu.unq.wannaplay.employee.Employee;

public class LicenceCalendar implements Serializable {
    private static final long serialVersionUID = 1L;

    private Map<String, List<Pair<String, Interval>>> employeesLicences;

    private int month;

    private int year;

    private int daysCant;

    private Interval monthInterval;

    public LicenceCalendar() {
        super();
    }

    public LicenceCalendar(final List<Employee> employees, final int month, final int year) {
        employeesLicences = this.getEmployeesLicencesMap(employees);
        this.month = month;
        this.year = year;

        final DateTime monthInit = new DateTime(year, month, 1, 0, 0, 0, 0);

        int nextYear = year;
        int nextMonth;
        if (month < 12) {
            nextMonth = month + 1;
        } else {
            nextMonth = 1;
            nextYear++;
        }
        final DateTime monthFinish = new DateTime(nextYear, nextMonth, 1, 0, 0, 0, 0).minusDays(1);

        monthInterval = new Interval(monthInit, monthFinish);
        daysCant = monthInterval.getEnd().getDayOfMonth();
    }

    private Map<String, List<Pair<String, Interval>>> getEmployeesLicencesMap(final List<Employee> employees) {
        Map<String, List<Pair<String, Interval>>> employeesLicencesMap = new HashMap<String, List<Pair<String, Interval>>>();

        for (Employee e : employees) {
            List<Pair<String, Interval>> licencesPairs = this.transformLicences(e.getRegister().getLicences());
            employeesLicencesMap.put(e.getData().getSurname() + ", " + e.getData().getId(), licencesPairs);
        }

        return employeesLicencesMap;
    }

    private List<Pair<String, Interval>> transformLicences(final List<Licence> licences) {
        List<Pair<String, Interval>> licencesPair = new ArrayList<Pair<String, Interval>>();
        for (Licence l : licences) {
            licencesPair.add(new Pair<String, Interval>(l.getName(), l.getInterval()));
        }
        return licencesPair;
    }

    public String getLicence(final String name, final String id, final int day) {
        List<Pair<String, Interval>> licences = employeesLicences.get(id);
        DateTime date = new DateTime(year, month, day, 0, 0, 0, 0);

        for (Pair<String, Interval> p : licences) {
            if (p.getFirst().equals(name)) {
                if (p.getSecond().contains(date)) {
                    return p.getFirst();
                }
            }
        }
        return null;
    }

    public String getHoliday(final String id, final int day) {
        return this.getLicence("Holiday", id, day);
    }

    public Set<String> getEmployeesNames() {
        return this.getEmployeesLicences().keySet();
    }

    public Map<String, List<Pair<String, Interval>>> getEmployeesLicences() {
        return employeesLicences;
    }

    public Map<Integer, String> getDayLicencesMap(final String name) {
        Map<Integer, String> map = new HashMap<Integer, String>();

        this.getEmployeesLicences().get(name);

        for (int day = 1; day < daysCant; day++) {
            map.put(day, this.getHoliday(name, day));
        }

        return map;
    }

    public void setEmployeesLicences(final Map<String, List<Pair<String, Interval>>> employees) {
        employeesLicences = employees;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(final int month) {
        this.month = month;
    }

    public int getYear() {
        return year;
    }

    public void setYear(final int year) {
        this.year = year;
    }

    public int getDaysCant() {
        return daysCant;
    }

    public void setDaysCant(final int daysCant) {
        this.daysCant = daysCant;
    }

    public static long getSerialversionuid() {
        return serialVersionUID;
    }

    public Interval getMonthInterval() {
        return monthInterval;
    }

    public void setMonthInterval(final Interval monthInterval) {
        this.monthInterval = monthInterval;
    }

}
